//
//  MazeGameVC.swift
//  MazeGame
//
//  Created by orienthong on 2018/12/18.
//  Copyright © 2018 OrientHong. All rights reserved.
//

import UIKit
import SceneKit

class MazeGameVC: UIViewController {
    //Common
    //View
    enum GameSceneState: Int {
        case welcome
        case levelControl
        case playGame
    }
    var sceneView = SCNView()
    var helper = GameHelper()
    var configurator = Configurator()
    
    lazy var gameScene: SCNScene = {
        let scene = SCNScene(named: "art.scnassets/scn/welcome.scn")
        return scene!
    }()
    
    lazy var gameNode: SCNNode = {
        let node = self.gameScene.rootNode.childNode(withName: "welcome", recursively: false)
        return node!
    }()
    
    var swipeUp: UISwipeGestureRecognizer!
    var swipeDown: UISwipeGestureRecognizer!
    
    // Nodes to manipulate the camera
    var cameraYHandle = SCNNode()
    var cameraXHandle = SCNNode()
    
    //var padTouch: UITouch?
    var panningTouch: UITouch?
    
    var lockCamera = true
    
    ///状态
    var sceneState: GameSceneState = .welcome
    
    //.welcome
    lazy var sphereNode: SCNNode = {
        let node = self.gameNode.childNode(withName: "sphere", recursively: true)!
        return node
    }()
    
    //.levelControl
    var currentPressLevelNode: SCNNode? = nil
    
    //.playGame
    var gameSphere: SCNNode {
        get {
            return self.gameScene.rootNode.childNode(withName: "gameSphere", recursively: true)!
        }
    }
    var firstPan = true
    
    /// 手指滑动屏幕的操作
    ///
    /// - camera: 旋转camera
    /// - sphere: 移动sphere
    enum PanningType {
        case camera
        case sphere
        case none
    }
    
    var panningType: PanningType = .none
    
    /// 分割线的y坐标
    lazy var divider: CGFloat = {
        return self.sceneView.frame.size.height * 1/3
    }()
    
    /// 相机朝向
    var cameraDircetion: Direction = .forward
    
    //手指滑动相关
    var previousFingerDirection: Direction = .forward
    var currentFingerDirection: Direction = .forward
    
    //小球当前位置
    var currentLocation: Location = Location(z: 14, x: 0)
    
    /// 俯瞰图
    var topSceneView: SCNView!
    
    var countNode: SCNNode!
    
    var countdownTimer: Timer!
    
    
    ///true为正在游戏，false为俯瞰记忆迷宫
    var isGamming: Bool = false
    
    lazy var rememberTotalTime: Int = {
       return self.configurator.time
    }()
    lazy var gammingTotalTime: Int = {
       return self.configurator.gameTimming
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
        configureSceneView()
        //animateSphere()
        setupCamera()
        
        //self.sceneView.showsStatistics = true
        self.sceneView.isMultipleTouchEnabled = false
    }
}
// Basic Setup
extension MazeGameVC {
    //: Mark - UI
    override var prefersStatusBarHidden: Bool {
        return true
    }
    func setupView() {
        self.view.backgroundColor = .white
        self.view.addSubview(self.sceneView)
        self.sceneView.translatesAutoresizingMaskIntoConstraints = false
        self.sceneView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        self.sceneView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        self.sceneView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        self.sceneView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
        
        self.topSceneView = SCNView()
        self.topSceneView.scene = self.gameScene
        self.view.addSubview(self.topSceneView)
        self.topSceneView.translatesAutoresizingMaskIntoConstraints = false
        self.topSceneView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
        self.topSceneView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 20).isActive = true
        self.topSceneView.widthAnchor.constraint(equalToConstant: self.view.frame.width/4).isActive = true
        self.topSceneView.heightAnchor.constraint(equalToConstant: self.view.frame.width/4).isActive = true
        self.topSceneView.pointOfView = self.gameScene.rootNode.childNode(withName: "topcamera", recursively: false)!
        self.topSceneView.layer.masksToBounds = true
        self.topSceneView.layer.cornerRadius = self.view.frame.width/8
        self.topSceneView.isHidden = true
    }
    func configureSceneView() {
        self.sceneView.scene = self.gameScene
        self.sceneView.allowsCameraControl = false
        self.sceneView.defaultCameraController.interactionMode = .orbitTurntable
        self.sceneView.defaultCameraController.target = SCNVector3Zero
        
        swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(swipeGesture(_:)))
        swipeUp.direction = [.up]
        self.sceneView.addGestureRecognizer(swipeUp)
        swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(swipeGesture(_:)))
        swipeDown.direction = [.down]
        self.sceneView.addGestureRecognizer(swipeDown)
    }
    
}

// Control
extension MazeGameVC {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        switch sceneState {
        case .welcome:
            break
        case .levelControl:
            self.levelControlTouchesBegan(touches, with: event)
        case .playGame:
            self.playGameTouchesBegan(touches, with: event)
        }
        
//        for _ in touches {
//            if panningTouch == nil {
//                panningTouch = touches.first
//            }
//        }
        //在Level Control界面，即背面
        
        
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        switch sceneState {
            case .welcome:
                break
            case .levelControl:
                self.levelControlTouchesMoved(touches, with: event)
            case .playGame:
                self.playGameTouchesMoved(touches, with: event)
        }
        
//        if let touch = panningTouch {
//            let displacement = (float2(touch.location(in: view)) - float2(touch.previousLocation(in: view)))
//            panCamera(displacement)
//        }
    }
    
    func commonTouchesEnded(_ touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let touch = panningTouch {
            if touches.contains(touch) {
                panningTouch = nil
            }
        }
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        switch sceneState {
        case .welcome:
            break
        case .levelControl:
            self.levelControlTouchesCancelled(touches, with: event)
        case .playGame:
            self.playGameTouchesCancelled(touches, with: event)
        }
        //commonTouchesEnded(touches, withEvent: event)
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        switch sceneState {
        case .welcome:
            break
        case .levelControl:
            self.levelControlTouchesEnded(touches, with: event)
        case .playGame:
            self.playGameTouchesEnded(touches, with: event)
        }
        commonTouchesEnded(touches, withEvent: event)
    }
}

// Camera Control
extension MazeGameVC {
    func setupCamera() {
        let ALTITUDE = 0.0
        let DISTANCE = 20.0
        
        let pov = self.sceneView.pointOfView!
        pov.eulerAngles = SCNVector3Zero
        pov.position = SCNVector3(0.0, 0.0, DISTANCE)
        
        cameraXHandle.rotation = SCNVector4(1.0, 0.0, 0.0, -.pi/2)
        cameraXHandle.addChildNode(pov)
        
        cameraYHandle.position = SCNVector3(0.0, ALTITUDE, 0.0)
        cameraYHandle.rotation = SCNVector4(0.0, 1.0, 0.0, 2.0 * .pi)
        cameraYHandle.addChildNode(cameraXHandle)
        
        self.sceneView.scene?.rootNode.addChildNode(cameraYHandle)
        
        // Animate camera on launch and prevent the user from manipulating the camera until the end of the animation.
        // Animate
        SCNTransaction.animateWithDuration(completionBlock: {
            //self.lockCamera = false
            self.sceneView.isUserInteractionEnabled = true
        }) {
            self.lockCamera = true
            self.sceneView.isUserInteractionEnabled = false
            
            let cameraYAnimation = CABasicAnimation(keyPath: "rotation.w")
            cameraYAnimation.toValue = 0.0
            cameraYAnimation.fromValue = -SCNFloat(Float.pi * 2.0 - Float.pi/2 - Float.pi/4 * 3.0) as NSNumber
            cameraYAnimation.isAdditive = true
            cameraYAnimation.beginTime = CACurrentMediaTime() + 0.5 // wait a little bit before stating
            cameraYAnimation.fillMode = CAMediaTimingFillMode.both
            cameraYAnimation.duration = 2.0
            cameraYAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            self.cameraYHandle.addAnimation(cameraYAnimation, forKey: nil)
            
            let cameraXAnimation = cameraYAnimation.copy() as! CABasicAnimation
            cameraXAnimation.fromValue = SCNFloat(Float.pi/2 - Float.pi/4 * 0.125) as NSNumber
            self.cameraXHandle.addAnimation(cameraXAnimation, forKey: nil)
        }
    }
    // MARK: Managing the Camera
    
    private func panCamera(_ direction: float2) {
        if lockCamera {
            return
        }
        
        var directionToPan = direction
        
        directionToPan *= float2(1.0, -1.0)
        
        let F = SCNFloat(0.01)
        
        // Make sure the camera handles are correctly reset (because automatic camera animations may have put the "rotation" in a weird state.
        SCNTransaction.animateWithDuration(0.0) {
            self.cameraYHandle.removeAllActions()
            self.cameraXHandle.removeAllActions()
            
            if self.cameraYHandle.rotation.y < 0 {
                self.cameraYHandle.rotation = SCNVector4(0, 1, 0, -self.cameraYHandle.rotation.w)
            }
            
            if self.cameraXHandle.rotation.x < 0 {
                self.cameraXHandle.rotation = SCNVector4(1, 0, 0, -self.cameraXHandle.rotation.w)
            }
        }
        
        // Update the camera position with some inertia.
        SCNTransaction.animateWithDuration(0.5, timingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)) {
            self.cameraYHandle.rotation = SCNVector4(0, 1, 0, self.cameraYHandle.rotation.y * (self.cameraYHandle.rotation.w - SCNFloat(directionToPan.x) * F))
            self.cameraXHandle.rotation = SCNVector4(1, 0, 0, self.cameraXHandle.rotation.w + SCNFloat(directionToPan.y) * F)
        }
    }
}
